package util;

import java.util.ArrayList;
import java.util.HashMap;
import org.dom4j.Document;
import org.dom4j.Element;

import bean.CommonInterface;
import dbConnection.DbConnection;

/**
 * Contains methods to handle CommonInterface bean.
 * 
 * @author tanjian
 * 
 */
public class CIUtil {

	private static final String TYPE_PARAM = "param";
	private static final String TYPE_ER = "er";

	/**
	 * Initiate a interface with definition from the xml file
	 * 
	 * @param ci
	 * @return
	 * @throws Exception
	 */
	public static CommonInterface initFromFile(CommonInterface ci)
			throws Exception {
		ci = defineFromFile(ci);

		// Initiate the parameter template from file
		ci.setParams(DOMUtil.toItemList(XmlUtil.toDOM(CommonInterface.class
				.getClassLoader().getResource(ci.getParamsPath()).getPath())));

		return ci;
	}

	public static CommonInterface init(CommonInterface ci) throws Exception {
		// Initiate the parameter template from file
		ci = CIUtil.setParams(ci);
		ci = CIUtil.setExpectedResult(ci);
		return ci;
	}

	public static CommonInterface recordER(CommonInterface ci) throws Exception {

		// Connect to server and get actual results
		ci.setExpResult(DOMUtil.toItemList(JsonUtil.toDOM(ConnectionUtil
				.getConn().conn(ci))));
		return ci;
	}

	public static void recordER(CommonInterface ci, String path)
			throws Exception {

		// Connect to server and get actual results
		XmlUtil.toXML(JsonUtil.toDOM(ConnectionUtil.getConn().conn(ci)), path);
	}

	public static CommonInterface setParamsFromFile(CommonInterface ci)
			throws Exception {
		if (null == ci.getParamsPath()) {
			throw new Exception("File path not found!");
		} else {
			// Initiate the parameter template from file
			ci.setParams(DOMUtil.toItemList(XmlUtil.toDOM(CommonInterface.class
					.getClassLoader().getResource(ci.getParamsPath()).getPath())));
		}
		return ci;
	}

	public static CommonInterface setERFromFile(CommonInterface ci)
			throws Exception {
		if (null == ci.getExpResultPath()) {
			throw new Exception("File path not found!");
		} else {
			// Initiate the expected result template from file
			ci.setExpResult(DOMUtil.toItemList(XmlUtil
					.toDOM(CommonInterface.class.getClassLoader()
							.getResource(ci.getExpResultPath()).getPath())));
		}
		return ci;
	}

	public static CommonInterface setFromFile(CommonInterface ci, String path,
			String type) throws Exception {
		if (getTypeParam().equals(type)) {
			ci.setParamsPath(path);
			return setParamsFromFile(ci);
		} else if (getTypeEr().equals(type)) {
			ci.setExpResultPath(path);
			return setERFromFile(ci);
		} else {
			throw new Exception("Ilegal type!");
		}
	}

	public static CommonInterface setParams(CommonInterface ci)
			throws Exception {
		ci.setParams(ItemUtil.getItemByType(ci.getId(), getTypeParam()));
		return ci;
	}

	public static CommonInterface setExpectedResult(CommonInterface ci)
			throws Exception {
		ci.setExpResult(ItemUtil.getItemByType(ci.getId(), getTypeEr()));
		return ci;
	}

	public static CommonInterface defineFromFile(CommonInterface ci)
			throws Exception {

		Document document = XmlUtil.toDOM(ci.getDefinition());

		// Get the root element
		Element root = document.getRootElement();

		// Transform to HashMap
		HashMap<String, Object> hm = DOMUtil.toHashMap(root);

		// Match the element in the map with ci object and set the values
		ci = (CommonInterface) ReflectUtil.setObjectValues(hm, ci);

		DbConnection.save(ci);

		return ci;
	}

	public static CommonInterface defineFromFile(String path) throws Exception {
		CommonInterface ci = new CommonInterface(path);
		return defineFromFile(ci);
	}

	public static CommonInterface getCiById(String commoninterfaceId)
			throws Exception {
		CommonInterface ci = new CommonInterface();
		ci.setId(commoninterfaceId);
		ArrayList<CommonInterface> alc = DbConnection.select(ci);
		if (alc.size() == 1) {
			return alc.get(0);
		} else if (alc.size() > 1) {
			throw new Exception("Too many results!");
		} else {
			throw new Exception("No suitable result!");
		}
	}

	public static CommonInterface getCiByName(String commoninterfaceName)
			throws Exception {
		CommonInterface ci = new CommonInterface();
		ci.setName(commoninterfaceName);
		ArrayList<CommonInterface> alc = DbConnection.select(ci);
		if (alc.size() == 1) {
			return alc.get(0);
		} else if (alc.size() > 1) {
			throw new Exception("Too many results!");
		} else {
			throw new Exception("No suitable result!");
		}
	}

	public static String getTypeParam() {
		return TYPE_PARAM;
	}

	public static String getTypeEr() {
		return TYPE_ER;
	}

}
